package com.cskayan.javase.object._2tostring;

import javax.xml.stream.events.StartDocument;

/**
 * toString方法
 * 1.方法的声明:
 *      public String toString()
 *      没有什么可注意的,这个方法不需要参数,只不过是将一个对象转换成字符串的表示形式
 * 2.方法的作用:
 *      关于toString方法的作用，在JDK文档中，有详细的说明，主要说以下四点：
 *      a.返回该对象（调用toString方法的对象）的字符串表示。
 *      b.通常，toString方法会返回一个“以文本方式表示”此对象的字符串。
 *      c.结果应是一个简明但易于读懂的信息表达式。
 *      d.建议所有(Object类)子类都重写此方法。
 * 3.Object类当中toString方法的默认实现:
 *         return getClass().getName() + "@" + Integer.toHexString(hashCode());
 *         hashCode()是Object类当中的一个方法,它是通过计算对象的地址得出一个十进制的值
 *              可以认为hashCode()方法的返回值是这个对象的十进制地址值
 *         然后Integer.toHexString(int)
 *              是将一个十进制的整数转换成十六进制的字符串
 *         Integer.toHexString(hashCode())整体表示这个对象的十六进制地址值
 *  以上默认实现的字符串是:
 *          全限定类名 + @ + 对象的十六进制地址值
 *
 *  重点:
 *        在Java当中,直接打印一个引用(名),都会自动调用该方法,打印对象的地址值
 *        而实际上,当你直接使用引用(名)参与"+"的拼接运算时,也会自动调用该类的toString方法
 *          是隐式调用,不需要程序员把方法调用代码写出来
 *
 * 4.默认情况下,toString方法会打印地址值,但是很多时候这不是我们希望看到的
 *      打印对象,往往最希望看到对象的属性(成员变量)取值
 *      于是需要在子类中重写toString方法,打印属性的取值
 *
 * 注意事项:
 *      1.toString方法如无特殊需求,建议不要手写,直接alt+insert快捷键自动生成.
 *
 *      2.toString方法就是为了打印成员变量取值的
 *          快捷键自动生成这个方法即可
 *          不要在这个方法中乱写代码
 *          尤其是赋值等业务代码
 *
 *          在debug模式下,当代码走过创建对象的语句或者使用对象的语句
 *              会自动调用该类的toString方法,然后在语句的后面打印信息
 *              乱写toString方法会引发错误
 *
 *     3.如果类中有引用数据类型成员变量,咋办?
 *          很简单,继续拼接字符串即可
 *              如果是String,直接拼接
 *              如果是其它引用数据类型就拼接引用
 *                  但是需要重写这个类型的toString方法
 *
 *
 *     4.不要画蛇添足.
 *          toString方法是隐含调用的
 *          在输出引用或者用引用拼接字符串时,隐式调用
 *          不要写出来
 *          这么做可以避免空指针异常
 *
 * @since 15:49
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // Student s = new Student(18, 100);
        // System.out.println(s);
        // System.out.println(s + " hello world!");
        // System.out.println(s.age);

        /*Student s2 = new Student(20, 120, "张三", new Star(10000));
        System.out.println(s2);*/

        Student s3 = new Student(100, 1000, "李四", null);
        System.out.println(s3);
    }
}

class Student {
    int age;
    double score;
    String name;
    Star s;

    public Student() {
    }

    public Student(int age, double score) {
        this.age = age;
        this.score = score;
    }

    public Student(int age, double score, String name) {
        this.age = age;
        this.score = score;
        this.name = name;
    }

    public Student(int age, double score, String name, Star s) {
        this.age = age;
        this.score = score;
        this.name = name;
        this.s = s;
    }

    /* @Override
    public String toString() {
        return "Student {" + "age = " + age +
                "score = " + score +
                "}";
    }*/

    /*@Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", score=" + score +
                ", name='" + name + '\'' +
                '}';
    }*/

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", score=" + score +
                ", name='" + name + '\'' +
                ", s=" + s +
                '}';
    }
}

class Star {
    double salary;

    public Star(double salary) {
        this.salary = salary;
    }

    public Star() {
    }

    @Override
    public String toString() {
        return "Star{" +
                "salary=" + salary +
                '}';
    }
}